package com.hzw.saas.common.verify.service.impl;

import java.util.Collection;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dm.model.v20151123.SingleSendMailRequest;
import com.aliyuncs.dm.model.v20151123.SingleSendMailResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.hzw.saas.common.config.util.AssertUtil;
import com.hzw.saas.common.util.AccountValidatorUtil;
import com.hzw.saas.common.verify.config.EmailAliyunConfig;
import com.hzw.saas.common.verify.service.IEmailService;
import com.hzw.saas.common.verify.util.TemplateUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 邮箱服务默认实现
 *
 * @author zzl
 * @since 01/11/2021
 */
@Slf4j
public class AliyunEmailServiceImpl implements IEmailService {

    private final EmailAliyunConfig config;

    private static final String VERIFY_TEMPLATE_PATH = "template/emailTemplate.html";
    private final String verifyCodeTemplate;

    public AliyunEmailServiceImpl(EmailAliyunConfig config) {
        this.config = config;
        this.verifyCodeTemplate = TemplateUtil.getTemplate(VERIFY_TEMPLATE_PATH);
    }

    @Override
    public void send(String to, String subject, String content, boolean isHTML) {
        AssertUtil.assertThrow("收件人不可为空", StrUtil.isBlank(to));
        AssertUtil.assertThrow("邮箱格式不正确", !AccountValidatorUtil.isEmail(to));

        IClientProfile profile = DefaultProfile.getProfile(config.getRegionId(), config.getAccessKey(), config.getSecretKey());
        IAcsClient client = new DefaultAcsClient(profile);
        SingleSendMailRequest request = new SingleSendMailRequest();
        request.setAccountName(config.getAccountName());
        request.setFromAlias(config.getFromAlias());
        request.setAddressType(1);
        // request.setTagName("VerifyCode");
        request.setReplyToAddress(false);
        request.setToAddress(to);
        //可以给多个收件人发送邮件，收件人之间用逗号分开，批量发信建议使用BatchSendMailRequest方式
        //request.setToAddress("邮箱1,邮箱2");
        request.setSubject(subject);
        //如果采用byte[].toString的方式的话请确保最终转换成utf-8的格式再放入htmlbody和textbody，若编码不一致则会被当成垃圾邮件。
        //注意：文本邮件的大小限制为3M，过大的文本会导致连接超时或413错误
        if (isHTML) {
            request.setHtmlBody(content);
        } else {
            request.setTextBody(content);
        }
        //SDK 采用的是http协议的发信方式, 默认是GET方法，有一定的长度限制。
        //若textBody、htmlBody或content的大小不确定，建议采用POST方式提交，避免出现uri is not valid异常
        request.setMethod(MethodType.POST);
        //开启需要备案，0关闭，1开启
        request.setClickTrace("0");
        try {
            //如果调用成功，正常返回httpResponse；如果调用失败则抛出异常，需要在异常中捕获错误异常码；错误异常码请参考对应的API文档;
            log.debug("发送[阿里云邮件] to {} ...", to);
            SingleSendMailResponse httpResponse = client.getAcsResponse(request);
            log.debug("发送[阿里云邮件] to {} 完成", to);
        } catch (ClientException e) {
            log.error("[阿里云]邮箱服务异常", e);
        }
    }

    @Override
    public void send(Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, boolean isHtml) {
        throw new RuntimeException("阿里云邮件暂不支持此功能");
    }

    @Override
    public String sendVerifyCode(String to, String subject, String code) {
        String content = this.verifyCodeTemplate.replace("{{code}}", code);
        send(to, subject, content, true);
        return code;
    }
}
